package com.ganzalang.gmall.learning.netty.bio;

import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Ganzalang
 * @description BIO服务端
 * @Date 2021/6/26 21:36
 */
@Slf4j
public class BioServer {

    public static void main(String[] args) {
        // 阿里开发规范必须指定参数来构造线程池
        ThreadPoolExecutor serverPoolExecutor = new ThreadPoolExecutor(10,
                20,
                10,
                TimeUnit.MINUTES,
                new LinkedBlockingDeque<>(10),
                new DefaultThreadFactory("server-pool"));
        // 服务端创建socket
        try {
            ServerSocket serverSocket = new ServerSocket(8099);
            log.info("服务端已启动");

            while (true) {
                log.info("服务端等待连接");
                Socket socket = serverSocket.accept();
                log.info("主线程" + Thread.currentThread().getId() + "接收到一个客户端请求连接");
                // 创建线程池，启动一个线程去与客户端通信
                serverPoolExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        // 处理客户端的信息
                        handler(socket);
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void handler(Socket socket) {
        try{
            // 存储客户端发来的信息
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket.getInputStream();
            while (true) {
                log.info("等待客户端发来数据...");
                // 从socket中读取发来的信息
                int read = inputStream.read(bytes);
                if (read != -1) {
                    // 输出客户端发来的信息
                    log.info("线程" + Thread.currentThread().getId() + "接收到数据：" + new String(bytes, 0, read));
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭与客户端的连接
            try {
                socket.close();
                log.info("客户端已关闭连接");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
